import tensorflow as tf

x = tf.random.uniform([4, 35, 8], maxval=100, dtype=tf.int32)
# gather获取指定维度下面的数据
# 在第0维收集第1、2号班级的成绩册，在第1维，第2维收集以此类推
y = tf.gather(x, [0, 1], axis=0)

# gather_nd 通过指定每次采样的多为坐标来实现采样多个点的目的
# 我们要采集第一个班第一个同学、第二个班第二个同学、第三个班第三个同学的所有科目，方法如下
result = tf.gather_nd(x, [[1, 1], [2, 2], [3, 3]])
print(result.shape)

# boolean_mask 通过给定掩码进行采样
mask = [True, False, False, True]
# 在0维度上对0、3号班级采样
tf.boolean_mask(x, mask, axis=0)
# 多维掩码采样
x = tf.random.uniform([2, 3, 8], maxval=100, dtype=tf.int32)  # 假设只有两个班，每班三个人
# 对第一个班的0、1号学生和第二个班的2、3号学生采样
tf.boolean_mask(x, [[True, True, False], [False, True, True]])

# where（cond,a,b）当cond[j] 为True时选择a[j],否则选b[j]
a = tf.ones([3, 3])
b = tf.zeros([3, 3])
cond = [[True, False, True], [True, False, True], [True, False, True]]
c = tf.where(cond, a, b)
print(c)
# 当a=b=None时，where会返回cond中所有元素为True的下标
c = tf.where(cond)
print(c)
# 例如：提取张量中所有正数的数据和索引
x = tf.random.normal([3, 3])
# 比较运算得到所有正数的掩码
mask = x > 0
# 通过where提取True的索引
indices = tf.where(mask)
# 通过gather_nd来提取数据
result = tf.gather_nd(x, indices)
print('所有正数', result)

# scatter_nd 向量刷新操作，但是只能刷新全为0的白板向量
indices = tf.constant([[4], [3], [1], [7]])
updates = tf.constant([4.4, 3.7, 5.1, 2.5])
# 在长度为8的全0向量上根据indices写入updates数据
result = tf.scatter_nd(indices, updates, [8])
print(result)

# meshgrid()能方便生成二维网格的采样点坐标
points = []

# 普通方式
# for x in range(-8, 8, 100):
#     for y in range(-8, 8, 100):
#         z = tf.sinc(x, y)
#         points.append(x, y, z)

# meshgrid方式
# 注意这里必须要是float型数据，因为取100个值必须要取到小数
x = tf.linspace(-8., 8, 100)
y = tf.linspace(-8., 8, 100)
x, y = tf.meshgrid(x, y)  # 生成网格点并内部拆分后返回
z = tf.sqrt(x ** 2 + y ** 2)
z = tf.sin(z) / z
from matplotlib import pyplot as plt
# 导入3D坐标轴支持
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
ax.contour3D(x.numpy(),y.numpy(),z.numpy(),50)
plt.show()
